Последний гвоздь в гроб Хаскеля/C++ в этом году!

TL;DR Больше микробенчмарков богу микробенчмарков!

Дошли руки до микробенчмарков, где известные фокусники всея Руси -- Лев Валкин и Сергей Зефиров тролят байтойобов и показывают, что если разложить Data Flow в свободные монады то получится что стрим можно выгребать пачками (генерируются MMX инструкции). Сегодня мы покажем, что в нашем цирке (Rust) иллюзионисты не хуже, а может быть даже и лучше.

Итак, как говорят хранители интернета, мы можем это написать двумя способами:

1. Циклы
2. Итераторы

Первое обычно относят к байтойобским языкам, а второе к чистым аппликативным, так как там это имеет смысл и реально сразу помогает для векторизации. Мы же напишем на расте и так и так и проверим:

#![feature(step_by)] pub fn lpa(sz: usize, iter_num: usize, ) -> usize { let mut sum = 0_usize; for e in 0..sz { sum = 0; let mut x: Vec = Vec::with_capacity(iter_num); for i in 0..iter_num { x.push(i); } let mut y: Vec = Vec::with_capacity(iter_num - 1); for i in 0..iter_num - 1 { y.push(x[i] + x[i + 1]); } for i in (0..iter_num).step_by(100) { sum += y[i]; } } sum } pub fn lpv(iter_num: usize, sz: usize) -> usize { let sums: Vec<_> = (0..iter_num) .map(|_| { let x: Vec<_> = (0..sz).map(|i| i).collect(); let y: Vec<_> = x.iter().zip(x.iter().skip(1)).map(|(x, y)| x + y).collect(); (0..sz).step_by(100).map(|i| y[i]).sum() }) .collect(); *sums.last().unwrap() } fn main() { println!("{:?}", lpa(20, 1000000)); } $ rustc -O main-lpv.rs $ time ./main-lpv 9999010000 real 0m0.055s user 0m0.044s sys 0m0.008s $ time ./main-lpa 9999010000 real 0m0.107s user 0m0.096s sys 0m0.012s

Теперь сишечка:

#include <stdint.h> #include <vector> #include <iostream> int main() { int64_t sum = 0; for(int e = 0; e < 20; e++) { sum = 0; std::vector<int64_t> x; x.reserve(1000000); for(int i = 0; i < 1000000; i++) { x.push_back(i); } std::vector<int64_t> y; y.reserve(1000000-1); for(int i = 0; i < 1000000-1; i++) { y.push_back(x[i] + x[i+1]); } for (int i = 0; i < 1000000; i += 100) { sum += y[i]; } } std::cout << sum << std::endl; } g++ main-c.cc -Ofast -march=native -funroll-loops -o main-c $ time ./main-c 9999010000 real 0m0.129s user 0m0.100s sys 0m0.028s

Теперь божественная "неоптимизированная" ГеАшЦешечка

{-# LANGUAGE ParallelListComp #-} import Control.Monad main = times 20 (compute 1000000) >>= print where times n m = do results <- replicateM n m return ((sum results) `seq` (head results)) compute n = do let xs = [0 .. (n-1)] ys = [x+k | x <- xs | k <- drop 1 xs] return $ sum $ map snd $ filter fst [((i`mod`100)==0,y) | y <- ys | i <- [0,1..]] $ ghc -O3 -o main-hs ./main-hs.hs $ time ./main-hs 9999010000 real 0m0.115s user 0m0.108s sys 0m0.004s

По требованию трудящихся на арену выходит божественный ЛуаДЖИТик:

ffi=require('ffi') jit.opt.start("hotloop=5", "loopunroll=100", "instunroll=100") jit.flush() local ct=ffi.typeof('int64_t[?]') function lpa(size, iter_num) local sum for e=0,size-1 do sum=0LL local x=ffi.new(ct, iter_num) for i=0,iter_num-1 do x[i]=i end local y=ffi.new(ct, iter_num-1) for i=0,iter_num-2 do y[i]=x[i]+x[i+1] end for i=0,iter_num-1,100 do sum = sum + y[i] end end return sum end print(lpa(20, 1000000)) os.exit(1) $ time luajit lpa.lua 9999010000LL real 0m0.099s user 0m0.032s sys 0m0.064s

Swift и Go -- ниже дна (С++). Поэтому эту хуйню даже ставить на машину не буду. Свифт лично мне нравится и желаю ему взросления, но его не будет так как Apple не технологичная компания уже (хотя за LLVM низкий поклон). С Go чуда не будет -- язык откровенно делался плохим (как и С++), поэтому его любят гидроцефалы с лоботомией пишущих лапшу вида if err != nil. Если видете чувака, который рекламиурет Go -- знайте, ебанат, инфа 100%. До существования Go эти люди называли себя системными администраторами (POSIX, KISS, UNIX, Керниган и Ритчи головного мозга), теперь гугл их пересадила из беша в гошечку. А мы вернемся из благодатного оазиса рассовой ненависти в лоно микробенчмарков.

Раздача шампанского:

Lang ms --------------- --- Rust Iterators 55 LuaJIT 2.1 99 Rust Arrays 107 GHC 115 C++ 119

С Новым Годом, Сережа и Лев!
Всем желаю успешного байтойобства и глубокого аппликативного фьюжена в 2017!